#region Copyright
// 
// Copyright (C) 2008 VirtualStaticVoid <virtualstaticvoid@gmail.com>
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#endregion

using System;
using System.Diagnostics;

namespace NAom.Core
{

  internal delegate TValue ValueGetter<TTarget, TValue>(TTarget target);
  internal delegate void ValueSetter<TTarget, TValue>(TTarget target, TValue value);

  internal class PropertyAccessor<TTarget, TValue> : IPropertyAccessor
    where TTarget: class
  {

    private readonly ValueGetter<TTarget, TValue> _getter;
    private readonly ValueSetter<TTarget, TValue> _setter;

    public PropertyAccessor(ValueGetter<TTarget, TValue> getter, ValueSetter<TTarget, TValue> setter)
    {
      if (getter == null) throw new ArgumentNullException("getter");
      if (setter == null) throw new ArgumentNullException("setter");

      _getter = getter;
      _setter = setter;
    }

    public TValue GetProperty(TTarget target)
    {
      if (target == null) throw new ArgumentNullException("target");
      Debug.Assert(_getter != null);
      return _getter(target);
    }

    public void SetProperty(TTarget target, TValue value)
    {
      if (target == null) throw new ArgumentNullException("target");
      Debug.Assert(_setter != null);
      _setter(target, value);
    }

    #region IPropertyAccessor Members

    object IPropertyAccessor.GetPropertyValue(object target)
    {
      if (target == null) throw new ArgumentNullException("target");
      return GetProperty((TTarget)target);
    }

    void IPropertyAccessor.SetPropertyValue(object target, object value)
    {
      if (target == null) throw new ArgumentNullException("target");
      SetProperty((TTarget)target, (TValue)value);
    }

    #endregion
  }

}
